#include<event2/event.h>
#include<event2/listener.h>
#include<iostream>
#include<string.h>
#include <signal.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
using namespace std;
struct Status{
    bool start = false;
    FILE *fp = 0; 
    string filename;
};
static void read_cb(bufferevent *bev,void *arg)
{
    Status *status=(Status *)arg;
    if(!status->start)
    {
        char data[1024]={0};
        bufferevent_read(bev,data,sizeof(data)-1);
        status->filename=data;
        bufferevent_write(bev,"ok",2);
        string out ="out\\";
        out+=data;
        //打开写入文件
        status->fp=fopen(out.c_str(),"wb");
        if(!status->fp)
        {
            cout<<"server open "<<out<<"failed"<<endl;
            return;
        }
        status->start=true;
        return;
    }
        //写入文件
    do {
    char data[1024]={0};
    int len = bufferevent_read(bev,data,sizeof(data));
    if(len>=0)
    {
        fwrite(data,1,sizeof(data),status->fp);
        fflush(status->fp);
    }
    }while(evbuffer_get_length(bufferevent_get_input(bev))>0);
    
}
static void event_cb(bufferevent *bev,short events,void *arg)
{
    cout<<"server_event_cb:"<<events<<endl;
    Status *status=(Status *)arg;
    if(events & BEV_EVENT_EOF)
    {
        cout<<"BEV_EVENT_EOF"<<endl;
        if(status->fp)
        {
            fclose(status->fp);
            status->fp=0;
            bufferevent_free(bev);
        }
    }
}
static bufferevent_filter_result filter_in(evbuffer *s,evbuffer *d,ev_ssize_t limit,bufferevent_flush_mode mode,void *arg)
{
    //接收客户端发送的文件名
    char data[1024]={0};
    int len=evbuffer_remove(s,data,sizeof(data)-1);
    cout<<"Server:"<<data<<endl;
    evbuffer_add(d,data,len);

    return BEV_OK;
}
static bufferevent_filter_result filter_out(evbuffer *s,evbuffer *d,ev_ssize_t limit,bufferevent_flush_mode mode,void *arg)
{
    return BEV_OK;
}
void listen_cb(struct evconnlistener * e, evutil_socket_t s, struct sockaddr * a, int socklen, void *arg)
{
    cout<<"listen_cb"<<endl;
    event_base* base=(event_base *)arg;

    //1.创建一个bufferevent 用于通信
    bufferevent *bev=bufferevent_socket_new(base,s,BEV_OPT_CLOSE_ON_FREE);
    Status *status=new Status();
    //2.添加输入过滤 并设置输入回调
    bufferevent *bev_filter=bufferevent_filter_new(bev,
        filter_in,
        0,
        BEV_OPT_CLOSE_ON_FREE,
        0,
        status
    );

    //3.设置回调,读取|事件回调 
    bufferevent_setcb(bev_filter,read_cb,0,event_cb,status);
    bufferevent_enable(bev_filter,EV_READ|EV_WRITE);
}
void Server(event_base * base)
{
    cout<<"Server begin"<<endl;
    sockaddr_in sin;
    memset(&sin,0,sizeof(sin));
    sin.sin_family=AF_INET;
    sin.sin_port=htons(6666);
    evconnlistener *ev=evconnlistener_new_bind(base,
    listen_cb,
    base,
    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,
    10,
    (sockaddr*)&sin,
    sizeof(sin)
);
}